~ function () {
  // 防止外面的变量 给他搞坏了
  'use strict';

  function Beam(i, w, fill) {
    this.i = i;
    this.x = canvas.width / 2;
    this.y = canvas.height / 2 + 80;
    this.sx = 40;
    this.sy = 0;
    this.w = w;
    this.fill = fill;
  }
  Beam.prototype.anim = function () {
    // pointer 是鼠标吗
    var dx = -this.x + pointer.x;
    var dy = -this.y + pointer.y;
    this.sx += dx / (this.i * 40);
    this.sy += dy / (this.i * 40);
    this.sx *= 0.98;
    this.sy *= 0.98;
    ctx.beginPath();
    ctx.moveTo(this.x, this.y);
    this.x += this.sx;
    this.y += this.sy;
    ctx.lineTo(this.x, this.y);
    // https://www.runoob.com/tags/canvas-lineto.html
    ctx.lineCap = 'round';
    ctx.lineWidth = this.w;
    ctx.strokeStyle = this.fill;
    // 颜色之类的
    ctx.stroke();
  }

  function run() {
    // https://developer.mozilla.org/zh-CN/docs/Web/API/Window/requestAnimationFrame
    requestAnimationFrame(run);
    var x = canvas.width * 0.008;
    var y = canvas.height * 0.008;
    // 挺小的数字啊
    ctx.drawImage(canvas.elem, -x, -y, canvas.width + x * 2, canvas.height + y * 2);
    if (n++ % 2 === 0) {
      ctx.fillStyle = 'rgba(0,0,0,0.1)';
      ctx.fillRect(0, 0, canvas.width, canvas.height);
    }
    // https://www.w3school.com.cn/tags/canvas_globalcompositeoperation.asp
    ctx.globalCompositeOperation = 'lighten';
    b0.anim();
    b1.anim();
    b2.anim();
    ctx.globalCompositeOperation = 'source-over';
  };
  // var canvasElm= document.createElement('canvas')
  // var canvasElm= document.getElementsByTagName('canvas')
  var beamElmId='beam'
  var canvasElm= document.getElementById(beamElmId)
    // var canvasElm= document.getElementById('canvas')
  var canvas = {
    elem:canvasElm,
    // elem: document.createElement('canvas'),
    resize: function () {
      // 这个 this.width 是直接来的吗
      this.width = this.elem.width = this.elem.offsetWidth;
      this.height = this.elem.height = this.elem.offsetHeight;
    },
    init: function (doAppend) {
      var ctx = this.elem.getContext('2d');
      if(doAppend){
        document.body.appendChild(this.elem);
      }
    
      window.addEventListener('resize', this.resize.bind(this), false);
      this.resize();
      return ctx;
    }
  };
  // var ctx = canvas.init();
  var ctx = canvas.init(false);
  var pointer = (function (canvas) {
    var pointer = {
      x: canvas.width / 2,
      y: canvas.height / 2,
      pointer: function (e) {
        var touchMode = e.targetTouches,
          pointer;
        if (touchMode) {
          e.preventDefault();
          pointer = touchMode[0];
        } else pointer = e;
        this.x = pointer.clientX;
        this.y = pointer.clientY;
      }
    };
    window.addEventListener('mousemove', function (e) {
      this.pointer(e);
    }.bind(pointer), false);
    canvas.elem.addEventListener('touchmove', function (e) {
      this.pointer(e);
    }.bind(pointer), false);
    return pointer;
  }(canvas));
  var n = 0;
  var b0 = new Beam(1, 80, 'hsl(47,80%,60%)');
  var b1 = new Beam(2, 80, '#fff');
  var b2 = new Beam(0.5, 80, '#00f');
  run();
}();